-- transfiguration
-- create by panyl
-- 变形术

return {
    apply = function(source, target, skillId, round, para, extra)
        -- 如果免疫了该技能
        if SkillM.immunitySkill(source, target, skillId) then
            SkillM.getSequence(target):immunity(source, target, skillId);
            return {};
        end

        -- 免疫该状态，也不处理了
        if CombatStatusM.immunityStatus(target, "transfiguration") then
            SkillM.getSequence(target):immunity(source, target, skillId);
            return {};
        end

        -- 禁锢抗性；skill里处理了部分效果，要先判断禁锢抗性
        local prop = PropM.combine(target, "durance_resist", 1);
        if PropM.apply(prop, 1) > 0 then
            if target.isAudience and target:isAudience() then
                -- 观众就不要提示了
            elseif not target:isDead() then
                if prop[4] == -1 then
                    doAlert(getLocStr("no_durance2"));
                else
                    doAlert(string.format(getLocStr("no_durance"), (prop[4] - round)));
                end
            end
            return {};
        end

        -- 无法被变形的
        if target.type == OBJECT_TYPE_MONSTER then
            local classId = target:query("class_id");
            local dbase = MonsterM.query(classId, "dbase") or {};
            if 1 == dbase["cant_be_trans"] then
                return {};
            end
        end

        local effectRound = -1;
        extra = extra or {};
        local lastRound = extra.lastRound;

        if type(lastRound) == "number" then
            effectRound = round + lastRound + 1;
        elseif para[2] > 0 then
            local v = para[2];
            -- 如果是boss
            if target:isBoss() then
                v = 2;
            end

            -- 计算魔法效果加成
            local addon_rate = SkillM.calcMagicEffectAddon(source, skillId, true);

            --最终威力
            v = math.modf(v * (addon_rate + 1000)/1000);

            -- 不包括本回合
            effectRound = round + v + 1;
        end

        -- 属性：持续时间+
        local addonRound = 0;
        prop = PropM.combine(source, "magic_last", skillId);
        addonRound = PropM.apply(prop, addonRound);
        prop = PropM.combine(source, "magic_last", "assist");
        addonRound = PropM.apply(prop, addonRound);
        prop = PropM.combine(source, "magic_last", "all");
        addonRound = PropM.apply(prop, addonRound);

        -- 如果是boss，持续时间减半
        if target:isBoss() then
            addonRound = extraCeil(addonRound, 2);
        end
        effectRound = effectRound + addonRound;

        -- 1. 威力
        local force = para[1];

        -- 如果是boss
        if target:isBoss() then
            force = math.modf(force / 2);
        end

        -- 先附加变形状态
        local condition = {
            ["value"] = force,
            ["end_round"] = effectRound,
        };
        CombatStatusM.applyStatus(target, "transfiguration", condition);

        -- 血量减少
        local currHp = target:getHp("hp");
        local reduceHp = math.modf(currHp * force / 1000);
        target:setRealHp(currHp - reduceHp);

        -- 清除增益状态（只清除buff）
        CombatStatusM.clearStatusByType(target, COM_STATUS_BUFF);
        -- 清除增益属性
        target.dbase:deleteTemp("prop", "buff");
        PropM.deleteProp(target, "skill", false);
        target.dbase:deleteTemp("prop", "equip");
        target.dbase:deleteTemp("prop", "special");

        -- 增加命中动作
        SkillM.getSequence(target):hit(source, target, skillId);

        if (target.type == OBJECT_TYPE_MONSTER
            or target.type == OBJECT_TYPE_GHOST_SHIP)
            and not target:isDead() then

            -- 怪物或者幽灵船，变形术变青蛙
            local dbase = {};
            if target.type == OBJECT_TYPE_MONSTER then
                dbase = MonsterM.query(target.classId, "dbase") or {};
            end

            local changeClassId = 2;
            if target:isBoss() and dbase["slime_display"] ~= 1 then
                changeClassId = 1;
            end
            if FormulaM.invoke("CAN_MONSTER_CHANGE_MODEL", target) then
                local pos = target.dbase:query("pos");
                if not pos then
                    pos = target:getOwner();
                end
                EventMgr.fire(event.GRID_CHANGE_MODEL,
                    {["pos"] = pos, ["changeClassId"] = changeClassId});
            end
        end

        EventMgr.fire(event.GRID_LOCK_STATE, {["pos"] = target:getPos(), });

        -- 作用目标
        return { target, };
    end,

    parse = function(desc)
        local arr = string.explode(desc, ",");
        return { tonumber(arr[1]), tonumber(arr[2] or -1) };
    end,

    -- 解析技能描述
    parseDesc = function(source, skillId, desc, para)
        local base = para[2];

        -- 计算魔法效果加成
        local addon_rate = SkillM.calcMagicEffectAddon(source, skillId, false);
        -- 最终威力
        local force = math.modf(base * (addon_rate + 1000)/1000);

        local addforce = 0;
        local prop = PropM.combine(source, "magic_last", skillId);
        addforce = PropM.apply(prop, addforce);
        prop = PropM.combine(source, "magic_last", "assist");
        addforce = PropM.apply(prop, addforce);
        -- 所有技能持续时间+
        prop = PropM.combine(source, "magic_last", "all");
        addforce = PropM.apply(prop, addforce);
        force = force + addforce;

        -- 1. 威力
        desc = string.gsub(desc, "{transfiguration}", para[1] / 10);

        -- 持续回合
        local addon = force - base;
        if addon == 0 then
            desc = string.gsub(desc, "{round}", force);
        else
            desc = string.gsub(desc, "{round}", base .. "(+" .. addon .. ")");
        end

        -- BOSS及PVP?的计算
        -- boss持续时间+属性，需要减半
        base = 2;
        force = math.modf(base * (addon_rate + 1000)/1000);
        addforce = extraCeil(addforce, 2);
        force = force + addforce;

        -- boss持续时间+属性也需要减半
        local addon = force - base;
        if addon == 0 then
            desc = string.gsub(desc, "{roundBoss}", force);
        else
            desc = string.gsub(desc, "{roundBoss}", base .. "(+" .. addon .. ")");
        end

        return desc;
    end,
};
